package gwt.immunology.shared;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.TreeSet;

import com.google.gwt.user.client.rpc.IsSerializable;

@SuppressWarnings("unused")
public class GenericDto extends HashMap<String, Object> implements IsSerializable {
    private static final long serialVersionUID = -5414893401302700859L;
    /**
     * Reference here any type you want to be added to the GWT whitelist
     * (java-to-js compilation list)
     */
    private Boolean simpleBoolean;
    private Long simpleLong;
    private Integer simpleInteger;
    private Double simpleDouble;
    private Date simpleDate;
    private HashSet<Long> simpleLongSet;
    private HashSet<String> simpleSet;
    private TreeSet<Double> simpleDoubleSet;
    private ResultSetDto simpleResultSetDto;
    private List<?> simpleList;
    private HashMap<String, String> deprecatedKeys = new HashMap<String, String>();
    
    public static class DefaultComparator implements Comparator<GenericDto> {
        private String key;

        public DefaultComparator(String key) {
            this.key = key;
        }

        @Override
        public int compare(GenericDto o1, GenericDto o2) {
            int res;
            Comparable value1 = o1.getComparable(key);
            Comparable value2 = o2.getComparable(key);
            
            if (value1 != null && value2 != null)
                res = o1.getComparable(key).compareTo(o2.getComparable(key));
            else if (value1 != null){
                res = -1;
            }else if (value2 != null){
                res = 1;
            }else{
                res = 0;
            }
            return res;
        }
    }
    

    public GenericDto() {
    }

    public Comparable getComparable(String key) {
        return (Comparable) super.get(key);
    }

    public GenericDto(HashMap<String, Object> map) {
        super(map);
    }

    @Override
    @Deprecated
    public Object get(Object key) {
    	String substitution = deprecatedKeys.get(key);
    	if (substitution != null) {
    		throw new RuntimeException("Key '" + key + "' is deprecated, switch to '" + substitution + "' ASAP");
    	}
        return super.get(key);
    }

    public void addDeprecatedKey(String key, String substitution) {
    	deprecatedKeys.put(key, substitution);
    }
    
    public Boolean getBoolean(String key) {
        return (Boolean) get(key);
    }

    public String getString(String key) {
        return get(key) != null ? get(key).toString() : null;
    }

    public Integer getInt(String key) {
        return (Integer) get(key);
    }

    public Double getDouble(String key) {
        return (Double) get(key);
    }

    public Long getLong(String key) {
        return (Long) get(key);
    }

    public HashSet<Long> getLongSet(String key) {
        return (HashSet<Long>) get(key);
    }

    public TreeSet<Double> getDoubleSet(String key) {
        return (TreeSet<Double>) get(key);
    }

    @Deprecated
    public long getLongId(String key) {
        Long res = (Long) get(key);
        if (res == null) {
            return 0;
        } else {
            return res;
        }
    }

    public Integer getIntId(String key) {
    	Integer res = (Integer) get(key);
    	return res != null ? res : 0;
    }
    
    public Date getDate(String key) {
        return (Date) get(key);
    }

    public GenericDto getGenericDto(String key) {
        return (GenericDto) get(key);
    }

    public ResultSetDto getResultSetDto(String key) {
        return (ResultSetDto) get(key);
    }

    public HashSet<Integer> getIntSet(String key) {
        return (HashSet<Integer>) get(key);
    }

    public List<?> getList(String key) {
        return (List<?>) get(key);
    }
    public HashSet<String> getSet(String key) {
        return (HashSet<String>) get(key);
    }
}
